// Copyright (c) 2008, 
// Marc Speck, http://www.faindu.com
// All Rights Reserved. The following is Source Code and is subject to all restrictions 
// on such code as contained in the license accompanying this product.
package com.faindu.editImage.move
{
import com.faindu.editImage.EditImage;
import com.faindu.editImage.base.BaseControl;
import com.faindu.editImage.base.BaseCursor;
import com.faindu.editImage.base.EditImageEvent;
import com.faindu.editImage.crop.CropCursor;

import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;

/**
 * There is no visible control for moving the image. However, for consistency,
 * everything for handling the move is here.
 */
public class MoveControl extends BaseControl
{
	/**
	 * Constructor
	 */
	function MoveControl( interactionMethod:Function ) 
	{
		super( interactionMethod, "move" )
		cursor = new MoveCursor()
	}
	
	/**
	 * Because the listeners are not attached to the instance of MoveControl but to imageHolder,
	 * <code>init</code> is overriden.
	 */
 	override public function init( editImage:EditImage, startInteractionHandler:Function, tool:Sprite ): void 
	{
		this.editImage = editImage
		editImage.imageHolder.addEventListener( MouseEvent.MOUSE_DOWN, dispatchMouseDownHandler )
		addEventListener( MouseEvent.MOUSE_DOWN, startInteractionHandler )
		tool.addChild( this )
		
		// show and hide cursor for control
 		editImage.imageHolder.addEventListener( MouseEvent.MOUSE_OVER, showCursor )
		editImage.imageHolder.addEventListener( MouseEvent.MOUSE_OUT, hideCursor ) 
		
		editImage.addEventListener( EditImageEvent.CONTROL_MOVE, controlMouseMove )

		if ( cursor )
		{
			cursor.visible = false
			addChild( cursor )
		}		
		
		draw()
	}
	
	/**
	 * Redispatch all <code>MouseEvent.MOUSE_DOWN</code>, because EditImage.startInteractionHandler()
	 * requires BaseControl as target.
	 */
	private function dispatchMouseDownHandler( mouseEvent:MouseEvent ): void
	{
		if ( enabled )
			dispatchEvent( mouseEvent.clone() )
	}
	
	public var enabled: Boolean = false
	
	/**
	 * @inheritDoc
	 */
	override protected function showCursor( mouseEvent:MouseEvent ): void
	{
		if ( cursor )
		{
			moveCursor( mouseEvent )
			cursor.visible = true
			editImage.imageHolder.addEventListener( MouseEvent.MOUSE_MOVE, moveCursor )
		}
	}

	/**
	 * @inheritDoc
	 */	
	override protected function hideCursor( mouseEvent:MouseEvent ): void
	{
		if ( cursor )
		{
			cursor.visible = false
			editImage.imageHolder.removeEventListener( MouseEvent.MOUSE_MOVE, moveCursor )
		}
	} 

	/**
	 * @inheritDoc
	 */		
 	override protected function moveCursor( mouseEvent:MouseEvent ): void
	{
		// this is more complicated because the event listener is editImage.imageHolder and
		// not this control. The point in imageHolder needs to transform into the position
		// in this control. What's also tricky that the imageHolder.scrollRect cuts the sprite, but
		// this is not reflected in imageHolder.transform.concatenatedMatrix.
		// When we transform backwards from imageHolder, the origin is editImage and not stage. We
		// can do this because imageHolder and moveControl are both attached to this origin.
		if ( cursor )
		{
			var imageHolderMatrix: Matrix = editImage.imageHolder.transform.matrix
			var moveControlMatrix: Matrix = transform.matrix
 			var imageScrollRect: Rectangle = editImage.imageHolder.scrollRect
 			
 			var innerMouseLoc: Point
  			if ( imageScrollRect )
	 			innerMouseLoc = new Point( 	mouseEvent.localX - imageScrollRect.x, 
	 										mouseEvent.localY - imageScrollRect.y )
	 		else
	 			innerMouseLoc = new Point( mouseEvent.localX, mouseEvent.localY )
	 		
 			moveControlMatrix.invert()
			imageHolderMatrix.concat( moveControlMatrix )
 			var movePoint: Point = imageHolderMatrix.transformPoint( innerMouseLoc )
			
  			cursor.x = movePoint.x + cursor.offset_x
			cursor.y = movePoint.y + cursor.offset_y
		}
	}	 	
}
}